/********************************************************************************
 * Project Name		[JavaEE_Web]
 * File Name     	[MessyCodeServlet.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package servlet.cases;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 解决中文乱码
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
@WebServlet(name = "MessyCodeServlet", urlPatterns = "/messyCode")
public class MessyCodeServlet extends HttpServlet {

	private static final long serialVersionUID = -6670273756408797365L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		outputChineseByStream(response);
		// outputChineseByWriter(response);
		// outputChineseByMetaTag(response);
		// outputNumber(response);
	}

	/**
	 * GET方式提交参数含有中文<br/>
	 * 
	 * 以下两种方式可以防止中文乱码<br/>
	 * 方式1:<br/>
	 * <code>
	 * String username = new String(request.getParameter("username").getByte("ISO-8859-1"),"UTF-8");
	 * </code>
	 * 
	 * 方式2: 修改server.xml<br/>
	 * <code>
	 * <Connector port="8080" connectionTimeout="20000" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>
	 * </code>
	 * 
	 * @param request
	 */
	private void inputParameterByGet(HttpServletRequest request) {
		String username = request.getParameter("username");
		System.out.println(username);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		inputParameterByPost(request);
	}

	/**
	 * POST方式提交参数含有中文, 在获取请求信息之前设置编码为UTF-8
	 * 
	 * @param request
	 * @throws UnsupportedEncodingException
	 */
	private void inputParameterByPost(HttpServletRequest request) throws UnsupportedEncodingException {
		request.setCharacterEncoding("UTF-8");
		inputParameterByGet(request);
	}

	/**
	 * 使用OutputStream向浏览器输出中文
	 * 
	 * 使用OutputStream流输出中文注意问题: <br/>
	 * 在服务器端数据是以哪个码表输出的, 那么就要控制客户端浏览器以相应的码表打开<br/>
	 * 比如:outputStream.write("中文".getBytes("UTF-8"));<br/>
	 * 此时要控制客户端浏览器以UTF-8的编码打开, 否则显示的时候就会出现中文乱码<br/>
	 * 服务器端可以通过设置响应头response.setHeader( "content-type",
	 * "text/html;charset=UTF-8");控制浏览器以UTF-8的编码显示数据<br/>
	 * 
	 * @param response
	 * @throws IOException
	 * @throws UnsupportedEncodingException
	 */
	protected void outputChineseByStream(HttpServletResponse response)
			throws IOException, UnsupportedEncodingException {
		String data = "这是第一个中文字符串";
		response.setHeader("content-type", "text/html;charset=UTF-8");
		OutputStream out = response.getOutputStream();
		out.write(data.getBytes("UTF-8"));
	}

	/**
	 * 使用PrintWriter向浏览器输出中文<br/>
	 * 
	 * 使用PrintWriter流输出中文注意问题:<br/>
	 * 首先使用response.setCharacterEncoding("UTF-8");设置字符以UTF-8的编码输出到浏览器<br/>
	 * 然后再使用response.setHeader("content-type", "text/html;charset=UTF-8");设置响应头,
	 * 然后再使用response.getWriter();获取PrintWriter输出流<br/>
	 * 控制浏览器以指定的字符编码编码进行显示<br/>
	 * 
	 * @param response
	 * @throws IOException
	 * @throws UnsupportedEncodingException
	 */
	protected void outputChineseByWriter(HttpServletResponse response)
			throws IOException, UnsupportedEncodingException {
		String data = "这是第二个中文字符串";
		// response.setHeader("content-type", "text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.write(data);
	}

	/**
	 * 使用HTML语言里面的<meta>标签来控制浏览器行为, 模拟通过设置响应头控制浏览器行为<br/>
	 * <code>
	 * out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");// 等价于
	 * response.setHeader("content-type", "text/html;charset=UTF-8");
	 * </code>
	 * 
	 * Chrome浏览器无效
	 * 
	 * @param response
	 * @throws IOException
	 * @throws UnsupportedEncodingException
	 */
	protected void outputChineseByMetaTag(HttpServletResponse response)
			throws IOException, UnsupportedEncodingException {
		response.setCharacterEncoding("UTF-8");
		String data = "这是第三个中文字符串";
		PrintWriter out = response.getWriter();
		out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
		out.write(data);
	}

	/**
	 * 输出数字
	 * 
	 * @param response
	 * @throws IOException
	 * @throws UnsupportedEncodingException
	 */
	protected void outputNumber(HttpServletResponse response) throws IOException, UnsupportedEncodingException {
		response.setHeader("content-type", "text/html;charset=UTF-8");
		OutputStream out = response.getOutputStream();
		out.write("使用OutputStream流输出数字1: ".getBytes("UTF-8"));
		// out.write(1); 无法得到输出结果
		out.write((1 + "").getBytes());
		// 使用PrintWriter输出数字也要将其转换为字符串
	}
}
